home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Comm / AmiTCP30b2.lha / src / util / finger / finger.c < prev    next >
C/C++ Source or Header  |  1994-05-03  |  11KB  |  387 lines

  1. /*
  2.  * finger.c - finger main program
  3.  *
  4.  * Copyright © 1993 AmiTCP/IP Group, <AmiTCP-group@hut.fi>
  5.  *                  Helsinki University of Technology, Finland.
  6.  *
  7.  * This program is derived from original work distributed in BSD Net 2.
  8.  *
  9.  * Created      : Fri Oct 15 01:29:07 1993 ppessi
  10.  * Last modified: Mon Feb 21 05:11:57 1994 ppessi
  11.  *
  12.  * $Log: finger.c,v $
  13.  * Revision 6.9  1994/05/02  19:41:27  jraja
  14.  * Changed for the new net.lib.
  15.  *
  16.  * Revision 6.8  1994/02/21  19:30:06  ppessi
  17.  * Removed tty field. Real release 2.
  18.  *
  19.  * Revision 6.7  1994/02/15  14:50:58  ppessi
  20.  * Added utmp support
  21.  *
  22.  * Revision 6.6  1994/01/21  13:51:31  ppessi
  23.  * Fixed docs..
  24.  *
  25.  * Revision 6.5  1994/01/21  13:46:13  ppessi
  26.  * Added documentation
  27.  *
  28.  * Revision 6.4  1994/01/21  13:37:27  ppessi
  29.  * Enabled "fuzzy" matching
  30.  *
  31.  * Revision 6.3  1993/10/18  15:45:30  ppessi
  32.  * Added real version tags.
  33.  *
  34.  * Revision 6.2  93/10/15  03:02:00  ppessi
  35.  * Removed -s support (until we got utmp from somewhere)
  36.  */
  37.  
  38. /****** utilities/finger *****************************************************
  39.  
  40.     NAME
  41.         finger - user information lookup program
  42.  
  43.     VERSION
  44.         $Id: finger.c,v 6.9 1994/05/02 19:41:27 jraja Exp $
  45.  
  46.     SYNOPSIS
  47.         finger [-lmsp] [user ...] [user@host ...]
  48.  
  49.     DESCRIPTION
  50.         The finger displays information about the system users.
  51.  
  52.         Options are:
  53.  
  54.     -s    Finger displays the user's login name, real name, login time
  55.               and host, office location and office phone number.
  56.  
  57.               Login time is displayed as month, day, hours and minutes,
  58.               unless more than six months ago, in which case the year is
  59.               displayed rather than the hours and minutes.
  60.  
  61.           Unknown hosts as well as nonexistent login time are
  62.           displayed as single asterisks.
  63.  
  64.         -l    Produces a multi-line format displaying the user's login name,
  65.               real name, the user's home directory, home phone number, login
  66.               shell, and the contents of the files `.forward', `.plan' and
  67.               `.project' from the user's home directory.
  68.  
  69.               Phone numbers specified as eleven digits are printed as
  70.               `+N-NNN- NNN-NNNN'.  Numbers specified as ten or seven digits
  71.               are printed as the appropriate subset of that string.  Numbers
  72.               specified as five digits are printed as `xN-NNNN'.
  73.  
  74.         -p    Prevents the -l option of finger from displaying the contents
  75.               of the `.forward', `.plan' and `.project' files.
  76.  
  77.         -m    Prevent matching of user names.  User is usually a login name;
  78.               however, matching will also be done on the users' real names,
  79.               unless the -m option is supplied.  All name matching performed
  80.               by finger is case insensitive.
  81.  
  82.         If no options are specified, finger defaults to the -l style output
  83.         if operands are provided, otherwise to the -s style.  Note that some
  84.         fields may be missing, in either format, if information is not
  85.         available for them.
  86.  
  87.         If no arguments are specified, finger will print an entry for each
  88.         user currently logged into the system.
  89.  
  90.         Finger may be used to look up users on a remote machine.  The format
  91.         is to specify a user as `user@host', or `@host', where the default
  92.         output format for the former is the -l style, and the default output
  93.         format for the latter is the -s style.  The -l option is the only
  94.         option that may be passed to a remote machine.
  95.  
  96.     SEE ALSO
  97.         in.fingerd
  98.  
  99.     HISTORY
  100.         The finger command appeared in 3.0BSD.
  101.  
  102. ****************************************************************************
  103. */
  104.  
  105. /*
  106.  * Finger prints out information about users.  It is not portable since
  107.  * certain fields (e.g. the full user name, office, and phone numbers) are
  108.  * extracted from the gecos field of the passwd file which other UNIXes
  109.  * may not have or may use for other things.
  110.  *
  111.  * There are currently two output formats; the short format is one line
  112.  * per user and displays login name, tty, login time, real name, idle time,
  113.  * and office location/phone number.  The long format gives the same
  114.  * information (in a more legible format) as well as home directory, shell,
  115.  * mail info, and .plan/.project files.
  116.  */
  117.  
  118. #include "finger_rev.h"
  119.  
  120. const char version[] = VERSTAG " "
  121.   "Copyright © 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>\n"
  122.   "Helsinki University of Technology, Finland.\n";
  123.  
  124. char BSD_copyright[] =
  125.   "@(#) Copyright (c) 1989 The Regents of the University of California.\n"
  126.   "All rights reserved.\n";
  127.  
  128. /*
  129.  * Copyright (c) 1989 The Regents of the University of California.
  130.  * All rights reserved.
  131.  *
  132.  * This code is derived from software contributed to Berkeley by
  133.  * Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
  134.  *
  135.  * Redistribution and use in source and binary forms, with or without
  136.  * modification, are permitted provided that the following conditions
  137.  * are met:
  138.  * 1. Redistributions of source code must retain the above copyright
  139.  *    notice, this list of conditions and the following disclaimer.
  140.  * 2. Redistributions in binary form must reproduce the above copyright
  141.  *    notice, this list of conditions and the following disclaimer in the
  142.  *    documentation and/or other materials provided with the distribution.
  143.  * 3. All advertising materials mentioning features or use of this software
  144.  *    must display the following acknowledgement:
  145.  *    This product includes software developed by the University of
  146.  *    California, Berkeley and its contributors.
  147.  * 4. Neither the name of the University nor the names of its contributors
  148.  *    may be used to endorse or promote products derived from this software
  149.  *    without specific prior written permission.
  150.  *
  151.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  152.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  153.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  154.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  155.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  156.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  157.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  158.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  159.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  160.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  161.  * SUCH DAMAGE.
  162.  */
  163.  
  164. #include <sys/types.h>
  165. #include <sys/param.h>
  166. #ifdef AMIGA
  167. #include <fcntl.h>
  168. #include <proto/usergroup.h>
  169. #include <clib/netlib_protos.h>
  170. #else
  171. #include <sys/file.h>
  172. #endif
  173. #include <stdio.h>
  174. #include <stdlib.h>
  175. #include "finger.h"
  176.  
  177. time_t now;
  178. int lflag, sflag, mflag, pplan;
  179.  
  180. PERSON *htab[HSIZE];        /* the buckets */
  181. PERSON *phead, *ptail;        /* the linked list of all people */
  182.  
  183. int entries = 0;
  184.  
  185. char tbuf[1024];
  186.  
  187. void loginlist(void);
  188. void userlist(register argc, register char **argv);
  189.  
  190. main(int argc, char **argv)
  191. {
  192.   extern int optind;
  193.   int ch;
  194.  
  195.   while ((ch = getopt(argc, argv, "lmps")) != EOF)
  196.     switch(ch) {
  197.     case 'l':
  198.       lflag = 1;        /* long format */
  199.       break;
  200.     case 'm':
  201.       mflag = 1;        /* force exact match of names */
  202.       break;
  203.     case 'p':
  204.       pplan = 1;        /* don't show .plan/.project */
  205.       break;
  206. #if HAVE_UTMP
  207.     case 's':
  208.       sflag = 1;        /* short format */
  209.       break;
  210. #endif
  211.     case '?':
  212.     default:
  213.       (void)fprintf(stderr,
  214. #if HAVE_UTMP
  215.             "usage: finger [-lmps] [login ...]\n"
  216. #else
  217.             "usage: finger [-lmp] [login ...]\n"
  218. #endif
  219.             );
  220.       exit(1);
  221.     }
  222.   argc -= optind;
  223.   argv += optind;
  224.  
  225.   (void)time(&now);
  226.  
  227.   if (!*argv) {
  228. #if !HAVE_UTMP
  229.     fprintf(stderr, "No utmp support yet.");
  230.     exit(0);
  231. #else
  232.     /*
  233.      * Assign explicit "small" format if no names given and -l
  234.      * not selected.  Force the -s BEFORE we get names so proper
  235.      * screening will be done.
  236.      */
  237.     if (!lflag)
  238.       sflag = 1;        /* if -l not explicit, force -s */
  239.     loginlist();
  240.     if (entries == 0)
  241.       (void)printf("No one logged on.\n");
  242. #endif
  243.   } else {
  244.     userlist(argc, argv);
  245.     /*
  246.      * Assign explicit "large" format if names given and -s not
  247.      * explicitly stated.  Force the -l AFTER we get names so any
  248.      * remote finger attempts specified won't be mishandled.
  249.      */
  250.     if (!sflag)
  251.       lflag = 1;        /* if -s not explicit, force -l */
  252.   }
  253.   if (entries != 0) {
  254. #if HAVE_UTMP
  255.     if (lflag)
  256.       lflag_print();
  257.     else
  258.       sflag_print();
  259. #else
  260.     lflag_print();
  261. #endif
  262.   }
  263.   exit(0);
  264. }
  265.  
  266. void
  267. loginlist(void)
  268. {
  269.   register PERSON *pn;
  270.   struct passwd *pw;
  271.   struct utmp *user;
  272.   char name[UT_NAMESIZE + 1];
  273.  
  274.   name[UT_NAMESIZE] = '\0';
  275.  
  276.   setutent();
  277.  
  278.   while (user = getutent()) {
  279.     if (!user->ut_name[0])
  280.       continue;
  281.  
  282.     if ((pn = find_person(user->ut_name)) == NULL) {
  283.       if ((pw = getpwnam(user->ut_name)) == NULL)
  284.     continue;
  285.       pn = enter_person(pw);
  286.     }
  287.     enter_where(user, pn);
  288.   }
  289.  
  290.   endutent();
  291.  
  292.   for (pn = phead; lflag && pn != NULL; pn = pn->next)
  293.     enter_lastlog(pn);
  294. }
  295.  
  296. void
  297. userlist(register argc, register char **argv)
  298. {
  299.   register i;
  300.   register PERSON *pn;
  301.   PERSON *nethead, **nettail;
  302. #if HAVE_UTMP
  303.   struct utmp *user;
  304. #endif
  305.   struct passwd *pw;
  306.   int dolocal, *used;
  307.  
  308.   if (!(used = (int *)calloc((u_int)argc, (u_int)sizeof(int)))) {
  309.     (void)fprintf(stderr, "finger: out of space.\n");
  310.     exit(1);
  311.   }
  312.  
  313.   /* pull out all network requests */
  314.   for (i = 0, dolocal = 0, nettail = &nethead; i < argc; i++) {
  315.     if (!index(argv[i], '@')) {
  316.       dolocal = 1;
  317.       continue;
  318.     }
  319.     pn = palloc();
  320.     *nettail = pn;
  321.     nettail = &pn->next;
  322.     pn->name = argv[i];
  323.     used[i] = -1;
  324.   }
  325.   *nettail = NULL;
  326.  
  327.   if (!dolocal)
  328.     goto net;
  329.  
  330.   /*
  331.    * traverse the list of possible login names and check the login name
  332.    * and real name against the name specified by the user.
  333.    */
  334.   if (mflag) {
  335.     for (i = 0; i < argc; i++)
  336.       if (used[i] >= 0 && (pw = getpwnam(argv[i]))) {
  337.     enter_person(pw);
  338.     used[i] = 1;
  339.       }
  340.   } else while (pw = getpwent())
  341.     for (i = 0; i < argc; i++)
  342.       if (used[i] >= 0 &&
  343.       (!strcasecmp(pw->pw_name, argv[i]) ||
  344.        match(pw, argv[i]))) {
  345.     enter_person(pw);
  346.     used[i] = 1;
  347.       }
  348.  
  349.   /* list errors */
  350.   for (i = 0; i < argc; i++)
  351.     if (!used[i])
  352.       (void)fprintf(stderr,
  353.             "finger: %s: no such user.\n", argv[i]);
  354.  
  355.   /* handle network requests */
  356.  net:
  357.   for (pn = nethead; pn; pn = pn->next) {
  358.     netfinger(pn->name);
  359.     if (pn->next || entries)
  360.       putchar('\n');
  361.   }
  362.  
  363. #if HAVE_UTMP
  364.   if (entries == 0)
  365.     return;
  366.  
  367.   /*
  368.    * Scan thru the list of users currently logged in, saving
  369.    * appropriate data whenever a match occurs.
  370.    */
  371.   setutent();
  372.  
  373.   while (user = getutent()) {
  374.     if (user->ut_name[0]) {
  375.       if ((pn = find_person(user->ut_name)) == NULL)
  376.     continue;
  377.       enter_where(user, pn);
  378.     }
  379.   }
  380.  
  381.   endutent();
  382.  
  383.   for (pn = phead; pn != NULL; pn = pn->next)
  384.     enter_lastlog(pn);
  385. #endif
  386. }
  387.